package chapter.fourth.item15;

/**
 * 声明不可变的类两种方式：
 * 一、类声明加上final关键字
 * 二、构造器加private关键字，并提供静态工厂方法
 * @author lzy
 *
 */
public final class Complex {
	private final double re;
	private final double im;
	
	public static final Complex ZERO = new Complex(0,0);
	public static final Complex ONE = new Complex(1,0);
	public static final Complex I = new Complex(0,1);
	
	//
	private Complex(double re,double im){
		this.re = re;
		this.im = im;
	}
	
	public double realPart(){return re;}
	public double imaginaryPart(){return im;}
	
	public Complex add(Complex c){
		return new Complex(re+c.re,im+c.im);
	}
	
	public Complex subtract(Complex c){
		return new Complex(re-c.re,im-c.im);
	}
	
	public Complex multiply(Complex c){
		return new Complex(re*c.re-im*c.im,
				re*c.im+im*c.re);
	}
	
	public Complex devide(Complex c){
		double tmp = c.re*c.re +c.im*c.im;
		return new Complex((re*c.re+im*c.im)/tmp,
				(im*c.re-re*c.im)/tmp);
	}

	@Override
	public int hashCode() {
		int result = 17+hashDouble(re);
		result = 31*result +hashDouble(im);
		return result;
	}

	private int hashDouble(double re2) {
		long longBits = Double.doubleToLongBits(re2);
		return (int)(longBits^(longBits>>>32));
	}

	@Override
	public boolean equals(Object obj) {
		if(obj==this){
			return true;
		}
		if(!(obj instanceof Complex))
			return false;
		Complex x = (Complex)obj;
		return Double.compare(re, x.re)==0&&
				Double.compare(im, x.im)==0;
	}

	@Override
	public String toString() {
		return "("+re+"+"+im+"i)";
	}
	
	public static Complex valueOf(double re,double im){
		return new Complex(re,im);
	}
	
	


}
